#!/usr/bin/perl -w

# $Id$

use strict;
use warnings;
use FindBin;
use lib "$FindBin::Bin/../libs";
use ABT::Global;
use ABT::Modules;
use Getopt::Long;
use Pod::Usage;
use WWW::Mechanize;

###################
# Script Variable #
###################

my $module_device = "[CONF] Ucopia";
my $module_description = "Module Ucopia (Backup by WebUI)";
my $author = 'Marc GUYARD <m.guyard@orange.com>';
my $version = '0.1';

#####################
# Default arguments #
#####################

my $GenConfigFile;
my $ConfigFile;
my $show_help;
my $show_man;
my $default_retention = "15";

#############
# Functions #
#############

## Function who show the module short description
sub description {
	print $program."\n	".$module_device." - ".$module_description." (version : ".$version.").\n\n";
}

## Function who generate a XML configuration file
sub generate {
	$logger->debug("[".$GenConfigFile."] Generating configuration file ") if $verbose;
	# Question function : 
	#	ARG1 : Question
	# 	ARG2 : Default Reply
	#	ARG3 : Reply is mandatory ? (1 => YES / 0 = NO)
	#	ARG4 : Function to verify the reply conformity
	my $device_ip_address = &questions("Please enter the Device IP to backup", "", "1", "verify_ip");
	my $device_description = &questions("Please enter the description of the device", "", "1", "");
	my $username = &questions("Please enter the device username", "admin", "1", "");
	my $password = &questions("Please enter the WebUi password", "", "1", "");
	my $webui_port = &questions("Please enter the WebUi port", "443", "1", "");
	my $store_folder = &questions("Please specify the folder who store the backup", "", "1", "verify_folder");
	my $file_prefix = &questions("Please enter the backup file prefix (date automaticly add)", "", "1", "");
	my $retention = &questions("Please enter configuration retention in number of save backup (leave empty to use the default retention : ".$default_retention.")", "", "0", "verify_retention");
	my %XML = (
		'enable' => '1',
		'module' => $program,
		'date' => $date,
		'ip' => $device_ip_address,
		'description' => $device_description,
		'username' => $username,
		'password' => $password,
		'webui-port' => $webui_port,
		'store-folder' => $store_folder,
		'file-prefix' => $file_prefix,
		'retention' => $retention,
		); ## To Update with all information need
	my $Config = new XML::Simple (NoAttr=>1, NoSort => 1, KeepRoot => 1);
	my $Config_data = $Config->XMLout({config=>\%XML}, outputfile=>$GenConfigFile, NoAttr=>1);
	$logger->info("[".$GenConfigFile."] Configuration generation finish... ");
}

## Function who backup device
sub backup {
	$logger->debug("[".$ConfigFile."] Starting backuping configuration ") if $verbose;
	# Declare all configuration from the XML file
	my $config_parsing = &parse_config($ConfigFile);
	my $device_ip_address = $config_parsing->{'ip'};
	my $username = $config_parsing->{'username'};
	my $password = $config_parsing->{'password'};
	my $webui_port = $config_parsing->{'webui-port'};
	my $store_folder = $config_parsing->{'store-folder'};
	my $file_prefix = $config_parsing->{'file-prefix'};
	my $retention = $config_parsing->{'retention'};
	# Test if $retention is empty. If empty, use $default_retention
	$retention = $default_retention if ( $retention eq "" );
	my $configuration_filename = $store_folder."/".$file_prefix."_".$date.".tar.bz2";
	# Backup
	my $mech = WWW::Mechanize->new( 
		agent => 'Backup NSOC NIS' ,
		autocheck => 0,
		ssl_opts => { verify_hostname => 0 }
	);
	my $login_page = "https://".$device_ip_address.":".$webui_port."/admin/";
	my $download_page = "https://".$device_ip_address.":".$webui_port."/admin/conf/download.php?mode=application%2Fx-bzip2&filename=saveconf&save=Sauvegarder";
	$logger->debug("[".$ConfigFile."] Trying to access to ".$login_page) if $verbose;
	$mech->get( $login_page );
	if ( $mech->success ) {
		$logger->debug("[".$ConfigFile."] Access to administration interface success") if $verbose;
		$logger->debug("[".$ConfigFile."] Trying to login to administration interface") if $verbose;
		$mech->set_fields(
        	monlogin => $username,
        	monpass => $password,
        );
        $mech->click;
        if ( $mech->content !~ /Erreur d\'authentification/ ) {
        	$logger->debug("[".$ConfigFile."] Login to administration interface success") if $verbose;
        	$logger->debug("[".$ConfigFile."] Trying to download backup to ".$download_page) if $verbose;
        	$mech->get( $download_page );
        	if ( $mech->success ) {
				# On recupere le contenu de la configuration
				$mech->save_content( $configuration_filename );
				if ($mech->success ) {
					$logger->debug("[".$ConfigFile."] Dowload backup succeeded") if $verbose;
				} else {
					print $logger->fatal("[".$ConfigFile."] Failed to download Backup. Return HTTP code : ".$mech->status()."\n");
				}
			} else {
				&return_code(50, "[".$ConfigFile."] Failed to get url (".$download_page."). Return HTTP code : ".$mech->status()." with message ".$mech->response->status_line);
			}
		} else {
			&return_code(50, "[".$ConfigFile."] Failed to get url (".$login_page."). Return HTTP code : ".$mech->status()." with message ".$mech->response->status_line);
		}
	} else {
		&return_code(50, "[".$ConfigFile."] Failed to get url (".$login_page."). Return HTTP code : ".$mech->status()." with message ".$mech->response->status_line);
	}
	# Purge old backup
	&purge_files($retention, $store_folder, "^".$file_prefix."_.*");
}

##########
# Script #
##########

# Check If arguments are present
if ( @ARGV > 0 ) {
	# Parse Arguments
	GetOptions( 	
		"d|description" => \&description,
		"c|config=s" => \$ConfigFile,
		"g|generate=s" => \$GenConfigFile,
		"v|verbose" => \$verbose,
		"q|quiet" => sub { $verbose = 0 },
		"man" => \$show_man,
		"h|help|?" => \$show_help 
	)
	# Show usage if no argument match
	or pod2usage({-message => "Argument unknown\n", -exitval => 1});
} else {
	# Show usage if no argument specified
	pod2usage({-message => "No argument specify\n", -exitval => 2});
}

# Show help usage
pod2usage(1) if $show_help;
# Show man usage
pod2usage(-verbose => 2) if $show_man;

# Call functions
&generate($GenConfigFile) if $GenConfigFile;
&backup($ConfigFile) if $ConfigFile;


__END__

=head1 NAME

ABTM - Another Backup Tool Module

=head1 AUTHOR

Script written by Marc GUYARD for Orange NIS <m.guyard@orange-ftgroup.com>.

=head1 VERSION

0.1 BETA PERL

=head1 SYNOPSIS

	Options:
		--description
			show the module description
		--config <configuration_file>
			use a configuration file specified
		--generate <configuration_file>
			generate a configuration file specified
		--verbose
			active script verbose
		--quiet
			active script quiet mode
		--man
			full documentation
		--help
			brief help message

=head1 OPTIONS

=over 8

=item B<--description>

Show the module description

=item B<--config>

Backup using a configuration file specify in argument.

=item B<--generate>

Generate a configuration file with the path and the name specify in argument.

=item B<--verbose>

Activate verbose mode. Should be used with another argument.

=item B<--quiet>

Activate quiet mode. Should be used with another argument.

=item B<--help>

Print a brief help message and exits.

=item B<--man>

Prints the manual page and exits.

=back

=head1 DESCRIPTION

B<This program> is a module of ABT (Another Backup Tool).

=head1 RETURN CODE

	Return Code :


=cut